package com.wyu.notaryserver.util;

/**
 * @author 六味lemontea 2025-01-25
 * @version 1.0
 * @description
 */
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ValidationUtil {
    /**
     * 校验出生日期是否合法（格式为 yyyy-MM-dd）
     * @param birthDate 出生日期字符串
     * @return true: 合法；false: 不合法
     */
    public static boolean ValidateBirthDate(String birthDate) {
        // 设置日期格式为 yyyy-MM-dd
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 禁用宽松模式，严格校验日期
        sdf.setLenient(false);
        try {
            // 尝试解析日期
            sdf.parse(birthDate);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }
    /**
     * 校验身份证
     *
     * @param idCard 身份证号
     * @return true: 校验通过；false: 校验失败
     */
    public static boolean validateIdCard(String idCard) {
        // 1. 校验长度
        if (idCard.length() == 18) {
            return isValid18(idCard);
        } else if (idCard.length() == 15) {
            return isValid15(idCard);
        }
        return false;
    }

    /**
     * 校验15位身份证
     *
     * @param idCard 15位身份证号
     * @return true: 校验通过；false: 校验失败
     */
    private static boolean isValid15(String idCard) {
        String ID_CARD_REGEX_15 = "^(\\d{15})$";  // 15位身份证
        // 15位身份证的正则校验
        Pattern pattern = Pattern.compile(ID_CARD_REGEX_15);
        Matcher matcher = pattern.matcher(idCard);
        if (matcher.matches()) {
            // 校验出生日期
            String birthDate = idCard.substring(6, 12);  // 生日部分是从第7到12位
            return isValidDate(birthDate, "yyMMdd");
        }
        return false;
    }

    /**
     * 校验18位身份证
     *
     * @param idCard 18位身份证号
     * @return true: 校验通过；false: 校验失败
     */
    private static boolean isValid18(String idCard) {
        String ID_CARD_REGEX_18 = "^(\\d{17})(\\d|X|x)$";  // 18位身份证
        // 18位身份证的正则校验
        Pattern pattern = Pattern.compile(ID_CARD_REGEX_18);
        Matcher matcher = pattern.matcher(idCard);
        if (matcher.matches()) {
            // 校验出生日期
            String birthDate = idCard.substring(6, 14);  // 生日部分是从第7到14位
            if (!isValidDate(birthDate, "yyyyMMdd")) {
                return false;
            }

            // 校验最后一位校验码
            return isValidChecksum(idCard);
        }
        return false;
    }

    /**
     * 校验日期是否合法
     *
     * @param date   日期字符串
     * @param format 日期格式
     * @return true: 合法；false: 不合法
     */
    private static boolean isValidDate(String date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setLenient(false);  // 禁止自动纠错
        try {
            sdf.parse(date);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 校验身份证的最后一位校验码
     *
     * @param idCard 18位身份证号
     * @return true: 校验通过；false: 校验失败
     */
    private static boolean isValidChecksum(String idCard) {
        // 18位身份证号的前17位数字（不包括最后的校验码）
        String idCardWithoutChecksum = idCard.substring(0, 17);
        // 校验位加权因子
        int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        // 校验位对应的字符
        char[] checkCodes = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += Integer.parseInt(String.valueOf(idCardWithoutChecksum.charAt(i))) * weights[i];
        }

        int mod = sum % 11;
        char checkCode = checkCodes[mod];
        // 校验码与身份证最后一位匹配
        return checkCode == idCard.charAt(17);
    }
}